package com.learn.fabric.app.demo.config;

import io.grpc.ManagedChannel;
import io.grpc.netty.shaded.io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.shaded.io.grpc.netty.NettyChannelBuilder;
import io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues.MessagePassingQueue;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hyperledger.fabric.gateway.*;
import org.hyperledger.fabric.protos.common.Common;
import org.hyperledger.fabric.sdk.BlockEvent;
import org.hyperledger.fabric.sdk.ChaincodeEvent;
import org.hyperledger.fabric.sdk.ChaincodeEventListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

/**
 * author he peng
 * date 2022/1/22 21:21
 *  gate_way 官方第一种方式
 */

@Configuration
@AllArgsConstructor
@Slf4j
public class HyperLedgerFabricGatewayConfig {

    final HyperLedgerFabricProperties hyperLedgerFabricProperties;

    @Bean
    public Gateway gateway() throws Exception {


        BufferedReader certificateReader = Files.newBufferedReader(Paths.get(hyperLedgerFabricProperties.getCertificatePath()), StandardCharsets.UTF_8);

        X509Certificate certificate = Identities.readX509Certificate(certificateReader);

        BufferedReader privateKeyReader = Files.newBufferedReader(Paths.get(hyperLedgerFabricProperties.getPrivateKeyPath()), StandardCharsets.UTF_8);

        PrivateKey privateKey = Identities.readPrivateKey(privateKeyReader);

        Wallet wallet = Wallets.newInMemoryWallet();

        wallet.put("user1" , Identities.newX509Identity(hyperLedgerFabricProperties.getMspId() , certificate , privateKey));


        Gateway.Builder builder = Gateway.createBuilder()
                .identity(wallet , "user1")
                .networkConfig(Paths.get(hyperLedgerFabricProperties.getNetworkConnectionConfigPath()));
//                .discovery(true);

        Gateway gateway = builder.connect();

        log.info("=========================================== connected fabric gateway {} " , gateway);

        return gateway;
    }
    @Bean
    public Network network(Gateway gateway) {

        return gateway.getNetwork(hyperLedgerFabricProperties.getChannel());
    }

    @Bean
    public Contract catContract(Network network) {

        network.addBlockListener(new Consumer<BlockEvent>() {
            @Override
            public void accept(BlockEvent blockEvent) {
                Common.Block block = blockEvent.getBlock();
                log.info("======================= block {} " , block);
                for (BlockEvent.TransactionEvent transactionEvent : blockEvent.getTransactionEvents()) {
                    log.info("====================== transactionEvent",transactionEvent.getBlockEvent());
                }
            }
        });

        Contract contract = network.getContract("hyperledger-fabric-contract-java-demo-learnCat");

        return contract;
    }







}
